x86 vmx: Streamline vmx_interrupt_blocked() to avoid a VMREAD if
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 13 Feb 2008 16:28:38 +0000 (16:28 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 13 Feb 2008 16:28:38 +0000 (16:28 +0000)
interrupt delivery is blocked by EFLAGS.IF. This speeds up real-mode
emulation in some cases (where we are currently executing
hvm_local_events_need_delivery() after every instruction).
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/vmx/vmx.c

index bdccd7b31229310ec395b303c843b6dc37ccae4d..8d4629df36d7c82e4eeb15f4f66e81885004ce12 100644 (file)
@@ -917,6 +917,14 @@ static enum hvm_intblk vmx_interrupt_blocked(
 {
     unsigned long intr_shadow;
 
+    /*
+     * Test EFLAGS.IF first. It is often the most likely reason for interrupt
+     * blockage, and is the cheapest to test (because no VMREAD is required).
+     */
+    if ( (intack.source != hvm_intsrc_nmi) &&
+         !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
+        return hvm_intblk_rflags_ie;
+
     intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
 
     if ( intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) )
@@ -929,9 +937,6 @@ static enum hvm_intblk vmx_interrupt_blocked(
     ASSERT((intack.source == hvm_intsrc_pic) ||
            (intack.source == hvm_intsrc_lapic));
 
-    if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
-        return hvm_intblk_rflags_ie;
-
     return hvm_intblk_none;
 }